﻿#pragma once
#include "ADFGlobal.h"

#include <QWidget>

#include "AsConfigUiTypeHandler.h"

//直接绑定
#define BIND_CONFIG_FIELD(_binderPtr,_obj,_var) _binderPtr->bindValue(#_var,&_obj._var)
//带前缀的绑定方式
#define BIND_CONFIG_FIELD_P(_binderPtr,_obj,_var,_prefix) _binderPtr->bindValue(#_prefix##"_"###_var,&_obj._var)

/*
	Tips：配置属性绑定器使用方法：

	------------1.在界面初始化的时候注册结构------------------
	m_pUiBinder=new AsConfigUiBinder(pConfig);
	BIND_CONFIG_FIELD(m_pUiBinder, m_pParam->param3D, transitionLength);
	---------------------------------------------------------

	------------2.在需要加载数据的地方调用------------------
	m_pUiBinder->loadFromConfig();
	---------------------------------------------------------

	------------3.在需要保存的地方调用------------------------
	m_pUiBinder->saveToConfig();
	-----------------------------------------------------------
*/

//配置属性绑定器
class ADF_EXPORT AsConfigUiBinder
{
	struct DataInfo 
	{
		QString typeName;									//类型名称
		void* pData=nullptr;								//数据指针
		QWidget* pControl = nullptr;						//控件指针
		AsConfigUiTypeHandler* pTypeHandler = nullptr;		//类型处理器
	};

public:
	AsConfigUiBinder(QWidget* pUi);

	template<typename _TYPE>
	void bindValue(QString keyName, _TYPE* data) {
		QString typeName = typeid(_TYPE).name();
		m_mapTypeData[keyName] = DataInfo({ typeName, data, nullptr,ADF::getTypeHandler(typeName)});
	}	

public:	
	void saveToConfig();					//保存到配置类
	void loadFromConfig();					//从配置类加载
	void bindTypeHandler(QString keyName,void* data,AsConfigUiTypeHandler* pHandler);	//自定义处理器

private:
	QWidget* m_pUi;

	QMap<QString, DataInfo> m_mapTypeData;
};

namespace ADF {

	/**
	 * 注册配置
	 */
	template<typename _TYPE, typename _HANDLER>
	void registerConfigUiTypeHandler()
	{
		if (std::is_base_of<AsConfigUiTypeHandler, _HANDLER>())
		{
			_HANDLER* pHandler = new _HANDLER();
			registerConfigUiTypeHandlerImpl(typeid(_TYPE).name(), pHandler);
		}
		else {
			qWarning() << typeid(_HANDLER).name() << " is not a child of AsConfigUiTypeHandler!";
		}
	}

	/**
	 * 配置类型解析器注册函数实现函数
	 */
	extern ADF_EXPORT void registerConfigUiTypeHandlerImpl(QString typeName, AsConfigUiTypeHandler* pHandler);

	/**
	 * 根据类型名称获取类型处理器
	 */
	extern ADF_EXPORT AsConfigUiTypeHandler* getTypeHandler(QString typeName);

	/**
	 * int-comboBox类型处理器
	 */
	extern ADF_EXPORT AsConfigUiTypeHandler* getEnumHandler();

}